home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
tex
/
src
/
specialhost
/
specialparse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-18
|
7KB
|
303 lines
/* specialparse.c */
/************************************************************************/
/* Some functions of this file are borrowed from Tomas Rokicki's */
/* printer driver "dvips". The functions GetKeyStr and GetKeyVal are, */
/* with little changes, from the file dospecial.c. */
/* "dvips" is a freely redistributable PostScript driver for dvi files. */
/* "dvips" is (C) Copyright 1987 by Tomas Rokicki. */
/* */
/* Georg Hessmann 26.06.1990 */
/************************************************************************/
KeyDesc KeyTab[] =
{{"ifffile", String}, /* ok */
{"hsize", Dimension}, /* ok */
{"vsize", Dimension}, /* ok */
{"hoffset", Dimension}, /* ok */
{"voffset", Dimension}, /* ok */
{"scale", Number}, /* not implemented */
{"hscale", Number}, /* not implemented */
{"vscale", Number}, /* not implemented */
{"mode", String}, /* new by MiL */
{"red", Number}, /* new by MiL */
{"green", Number}, /* new by MiL */
{"blue", Number}, /* new by MiL */
{"gamma", Number}}; /* new by MiL */
#define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
/* local funktions */
static void offset_to_inch (float *, float *, unsigned short);
static char *GetKeyStr (char *str, KeyWord *kw);
static int GetKeyVal (KeyWord *kw, KeyDesc tab[],
int nt, int *tno);
/******* P A R S E R *******************/
/* Umrechnung von 'offset' nach inch */
static void offset_to_inch(float *inch,float *offset,unsigned short einh)
{
float temp;
/** einh == pt|pc|in|bp|cm|mm|dd|cc **/
switch (einh) {
case 0x7074: /* pt */
temp = (float)*offset / 72.27;
break;
case 0x7063: /* pc */
temp = (float)*offset / 6.0225;
break;
case 0x696e: /* in */
temp = (float)*offset;
break;
case 0x6270: /* bp */
temp = (float)*offset / 72.0;
break;
case 0x636d: /* cm */
temp = (float)*offset / 2.5322;
break;
case 0x6d6d: /* mm */
temp = (float)*offset / 25.322;
break;
case 0x6464: /* dd */
temp = (float)*offset / 67.3467;
break;
case 0x6363: /* cc */
temp = (float)*offset / 5.6146;
break;
default:
temp = *offset; /* NOP */
break;
}
*inch = temp;
}
/**********************************************************************/
/***************************** GetKeyStr ****************************/
/**********************************************************************/
/* extract first keyword-value pair from string (value part may be null)
* return pointer to remainder of string
* return NULL if none found
*/
static char *GetKeyStr( char *str, KeyWord *kw )
{
char *s, *k, *v, t;
if ( str== NULL ) {
return( NULL );
}
for ( s=str; *s == ' '; s++ ); /* skip over blanks */
if ( *s == '\0' ) {
return( NULL );
}
for ( k=kw->Key; /* extract keyword portion */
(*s != ' ') && (*s != '\0') && (*s != '=');
*k++ = *s++ );
*k = '\0';
v = NULL;
kw->Val[0] = '\0';
kw->vt = None;
for ( ; *s == ' '; s++ ); /* skip over blanks */
if ( *s != '=' ) { /* look for "=" */
return( s );
}
for( s++ ; *s == ' '; s++ ); /* skip over blanks */
if ( *s == '\'' || *s == '\"' ) { /* get string delimiter */
t = *s++;
}
else {
t = ' ';
}
for (v=kw->Val; /* copy value portion up to delim */
*s != t && *s != '\0';
*v++ = *s++ ) ;
if ( t != ' ' && *s == t ) {
s++;
}
*v = '\0';
kw->vt = String;
return( s );
}
/**********************************************************************/
/***************************** GetKeyVal ****************************/
/**********************************************************************/
/* get next keyword-value pair
* decode value according to table entry
*/
static int GetKeyVal( KeyWord *kw, KeyDesc tab[], int nt, int *tno)
{
int i;
unsigned short ei;
char *einh;
float f;
einh = (char *)&ei;
ei = 0;
*tno = -1;
for(i=0; i<nt; i++) {
if ( !strcmp(kw->Key, tab[i].Entry) ) {
*tno = i;
switch ( tab[i].Type ) {
case None:
if ( kw->vt != None ) {
return( FALSE );
}
break;
case String:
if ( kw->vt != String ) {
return( FALSE );
}
break;
case Integer:
if ( kw->vt != String ) {
return( FALSE );
}
if ( sscanf(kw->Val,"%d", &(kw->v.i)) != 1) {
return( FALSE );
}
break;
case Dimension:
if (kw->vt != String ) {
return( FALSE );
}
if (sscanf(kw->Val,"%f%2s", &f, einh) != 2) {
return( FALSE );
}
offset_to_inch((float *)&(kw->v.n),&f,ei);
break;
case Number:
if ( kw->vt != String ) {
return( FALSE );
}
if( sscanf(kw->Val,"%f", &(kw->v.n)) != 1) {
return( FALSE );
}
break;
}
kw->vt = tab[i].Type;
return( TRUE );
}
}
return( TRUE );
}
/*--------------------------------------------------------------------*/
/**********************************************************************/
/**************************** ParseSepcial **************************/
/**********************************************************************/
void ParseSpecial (char *str, struct parse_result *res)
/* interpret a \special command, made up of keyword=value pairs */
{
KeyWord k;
int i;
while( (str=GetKeyStr(str,&k)) != NULL ) { /* get all keyword-value pairs */
/* for compatibility, single words are taken as file names */
if ( k.vt == None /* && access(k.Key,0) == 0 */) {
strcpy(res->iffile, k.Key);
}
else if (GetKeyVal(&k, KeyTab, NKEYS, &i) && i != -1) {
switch (i) {
case IFFILE:
strcpy(res->iffile, k.Val);
break;
case HSIZE:
res->hsize = k.v.n;
break;
case VSIZE:
res->vsize = k.v.n;
break;
case HOFFSET:
res->hoffset = k.v.n;
break;
case VOFFSET:
res->voffset = k.v.n;
break;
case SCALE:
res->scale = k.v.n;
break;
case HSCALE:
res->hscale = k.v.n;
break;
case VSCALE:
res->vscale = k.v.n;
break;
case MODE:
if (!strcmp(k.Val, "bw")) res->mode = BandW;
else if (!strcmp(k.Val, "gray"))
{
res->mode = Gray;
res->red = 1.0;
res->green = 1.0;
res->blue = 1.0;
}
else if (!strcmp(k.Val, "color"))
{
res->mode = Color;
res->red = 2.99;
res->green = 5.87;
res->blue = 1.14;
}
else if (!strcmp(k.Val, "ham"))
{
res->mode = Ham;
res->red = 2.99;
res->green = 5.87;
res->blue = 1.14;
}
else res->mode = BandW;
break;
case RED:
res->red = k.v.n;
break;
case GREEN:
res->green = k.v.n;
break;
case BLUE:
res->blue = k.v.n;
break;
case GAMMA:
res->gamma = k.v.n;
break;
default:
pline("%f @%s\n", k.v.n, KeyTab[i].Entry);
break;
}
}
else {
pline("Invalid keyword or value in \\special: (%d)",i);
pline(" \"%s\" ignored", k.Key );
}
}
}